/*
 Cogumelo v0.1 - INNOTO
Copyright (C) 2010 Innoto Gestión para el Desarrollo Social S.L. <mapinfo@innoto.es>

This program is free software; you can redistribute it and/or
modify it under the2009 terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
USA.
*/

var Map = Class.create
({
	
	init: function(id, opts)
	{
		//
		//	Options to send to server
		//
		this.bio = new Object({
			sw_lat_old: null,
			sw_lng_old: null,
			ne_lat_old: null,
			ne_lng_old: null
		});
		
		
		// Default map options
		this.options = new Object({
			dataurl: false,
			zoomlevel: 4,
			zoommax: null,
			zoommin: null,
			dynload: false,
			maptype: G_NORMAL_MAP ,
			mousescroll: true,
			startpoint: [43.374857,-8.406335],
			defaultcontrols: true,
			clustermarkers: false, // Cluster the markers
			tinyiconsmode: 7,// 'normal': show only normal icons, 'auto' (not suported yet): show tinyicons in the zoomlevel defined in points database, number: shows tinyicons when zoom is = or less than number
			iconarray: false
		});
		
		$.extend(true, this.options, opts);
		
		
		this.id = id;
		this.data = null;
		this.markers = new Array();
		this.markerCluster = null;
		
		// Init GMap2
		this.map = new GMap(document.getElementById(id));
		this.map.setMapType(this.options.maptype);
		var burnsvilleMN = new GLatLng(this.options.startpoint[0], this.options.startpoint[1]);
		this.map.setCenter(burnsvilleMN, this.options.zoomlevel);
		if(this.options.defaultcontrols == true)
			this.map.setUIToDefault();
		
		if(this.options.mousescroll == true)
			this.map.enableScrollWheelZoom();
		else
			this.map.disableScrollWheelZoom(); 

		// Begin map events listening
		this.lisenEvents();
		
		// Load data
		this.loadData();
	},
	

	//
	// Refresh map object status into this.bio
	refreshBio: function(){
		// set zoom value
		this.bio.oldzoomlevel = this.bio.zoomlevel;
		this.bio.zoomlevel = this.map.getZoom();
		////alert(this.bio.oldzoomlevel+'-'+this.bio.zoomlevel)
		// save old map limits
		this.bio.sw_lat_old = this.bio.sw_lat_new;
		this.bio.sw_lng_old = this.bio.sw_lng_new;
		this.bio.ne_lat_old = this.bio.ne_lat_new;
		this.bio.ne_lng_old = this.bio.ne_lng_new;
		
		// set new map limits
		this.bio.sw_lat_new = this.map.getBounds().getSouthWest().lat(); //South West latitude
		this.bio.sw_lng_new = this.map.getBounds().getSouthWest().lng(); //South West longitude
		this.bio.ne_lat_new = this.map.getBounds().getNorthEast().lat(); //North East latitude
		this.bio.ne_lng_new = this.map.getBounds().getNorthEast().lng(); //North East longitude

		var that = this;
		/*var polyline = new GPolyline([
		                              that.map.getBounds().getSouthWest(),
		                              that.map.getBounds().getNorthEast()
		                            ], "#ff0000", 10);
		this.map.addOverlay(polyline);*/
	
	},
	
	//
	// Load Json data
	loadData: function(notRefreshBio)
	{
		var that = this;
		
		
		// refrech map parameters
		if(notRefreshBio != true)
			this.refreshBio();
		
		if(this.options.dataurl) {

		  
			$.ajax({
				url: this.options.dataurl ,
				dataType: 'json',
				type: 'POST',
				data:  that.bio,
				success: function(data){
					that.data = data;
				},
				async:false
			});
			if(this.data != null)
				this.drawMarkers();
		}
		
	},
	
	// draw markers
	drawMarkers: function()
	{
		
		var that = this;

		// if dynamical load is active, clear the markers out of screen
		if(that.options.dynload)
			this.clearOutMarkers();


		$.each(this.data, function(index, value) {
			var point = new GLatLng(value.lat, value.lng);

			
			// select icon type from array (only if array exist)
			var ic=false;
			if(that.options.iconarray != false ){
				$.each(that.options.iconarray, function(ind, icon) {
					// find icon id in icons array
					if(icon.id == value.icon)
						ic = icon;
				});
			}
			else
				ic = new MapPointType(value.icon);

			// Creating Normal marker or light marker
			if(that.options.tinyiconsmode == 'normal' ||  (that.options.tinyiconsmode <20 && that.options.tinyiconsmode > 0  && that.options.tinyiconsmode < that.map.getZoom() ))
				var marker = new GMarker(point, ic.icon);
			else
				var marker = new MarkerLight(point, ic.tiny);
			
			$.extend(true, marker, {id:value.id});
			
			// creating marker event
			that.lisenMarker( marker, value );
			
			// print only if marker not in map or first load
			if(that.wasMapIn(marker) != false || that.bio.sw_lat_old == null) {
				if(that.options.clustermarkers == false) that.map.addOverlay(marker);
				// adding to markers array
				that.markers.push(marker);
			}
		});
		
		// cluster markers
		if(that.options.clustermarkers == true)
			this.markerCluster = new MarkerClusterer(this.map, this.markers);
	},
	
	// clear out of screen Markers
	clearOutMarkers: function()
	{
		var that = this;
        
		// clean marker cluster
		if(that.options.clustermarkers == true && this.markerCluster)
			this.markerCluster.clearMarkers();
		
		// markers array after clean
		var newmarkersarray = new Array()
		
		$.each( this.markers, function(index, value) {
			// If marker is out of screen
			if(	that.isMapOut(value))
					value.remove();
			else
				newmarkersarray.push(value);
				
		});
		
		// set new markers array without old markers
		this.markers = newmarkersarray;
		
		
	},
	
	// redraw all markers in the map
	reloadMarkers: function()
	{
		this.bio.sw_lat_old = false;
		this.bio.sw_lng_old = false;
		this.bio.ne_lat_old = false;
		this.bio.ne_lng_old = false;
		
		$.each( this.markers, function(index, value) {
					value.remove();
		});
		
		this.markers = new Array();
		
		this.loadData(true);
	},
	//returns True when a coord is out of map
	isMapOut: function(point){
		
		// check if changed the
		if(		(this.options.tinyiconsmode > 0 && this.options.tinyiconsmode < 100) &&
				(this.bio.oldzoomlevel > this.options.tinyiconsmode && this.bio.zoomlevel <= this.options.tinyiconsmode) ||
				(this.bio.zoomlevel  > this.options.tinyiconsmode && this.bio.oldzoomlevel <= this.options.tinyiconsmode)
		
		)
			return true;
		// check if is normal or lightmarker
		if(point.latlng)	
			var pointlatlng = point.latlng;
		else
			var pointlatlng = point.getLatLng();
			
        var SW = this.map.getBounds().getSouthWest();
        var NE = this.map.getBounds().getNorthEast();
        
		if(		pointlatlng.lat() < SW.lat() ||
				pointlatlng.lng() < SW.lng() ||
				pointlatlng.lat() > NE.lat() ||
				pointlatlng.lng() > NE.lng()
        )
			return true;
		else 
			return false;
	},
	
	//returns True when a coord was in last map area
	wasMapIn: function(point){
		
		if(		(this.options.tinyiconsmode > 0 && this.options.tinyiconsmode < 100) &&
				(this.bio.oldzoomlevel > this.options.tinyiconsmode && this.bio.zoomlevel <= this.options.tinyiconsmode) ||
				(this.bio.zoomlevel  > this.options.tinyiconsmode && this.bio.oldzoomlevel <= this.options.tinyiconsmode)
		
		)
			return true;
		// check if is normal or lightmarker
		if(point.latlng)	
			var pointlatlng = point.latlng;
		else
			var pointlatlng = point.getLatLng();
		
		if(this.bio.sw_lat_old == null) return false;
	
		if(		pointlatlng.lat() < this.bio.sw_lat_old ||
				pointlatlng.lng() < this.bio.sw_lng_old ||
				pointlatlng.lat() > this.bio.ne_lat_old ||
				pointlatlng.lng() > this.bio.ne_lng_old
        )
			return true;
		else 
			return false;
	},
	
	// Zoom in
	zoomIn: function ()
	{
		this.map.zoomIn();
	},
	
	// Zoom out
	zoomOut: function()
	{
		this.map.zoomOut();
	},
	
	//
	//	Listening the general map events
	lisenEvents: function()
	{
		var that = this;

	
		// When movement or zoom finish
		GEvent.addListener(this.map, 'moveend', function(){
			that.mapChange();

			if(that.options.zoommax && that.map.getZoom() > that.options.zoommax)
				that.map.setZoom( that.options.zoommax )
			else
			if(that.options.zoommin && that.map.getZoom() < that.options.zoommin)
				that.map.setZoom( that.options.zoommin )
			else {
				if(that.options.dynload)
					that.loadData();
			}
		});
	},
	
	
	//
	//		set Marker Event
	//
	lisenMarker: function(marker, markerdata) 
	{
		var that = this;
		GEvent.addListener(marker,"click", function(){ 
			//that.map.panTo(marker.getLatLng());
			that.markerClick(marker, markerdata);
		}); 
		
		GEvent.addListener(marker,"mouseover", function(){ 
			//that.map.panTo(marker.getLatLng());
			that.markerHover(marker, markerdata);
		});

		GEvent.addListener(marker,"mouseout", function(){ 
			//that.map.panTo(marker.getLatLng());
			that.markerOut(marker, markerdata);
		});

	},
	
	markerClick: function(marker, markerdata)
	{
		
	},

	markerHover: function(marker, markerdata)
	{
		
	},
	
	markerOut: function(marker, markerdata)
	{
		
	},
	
	mapChange: function() {
		
	}
});
